include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>

#define SIZE 1024
#define MAX_ARGC 64
#define SEP " "

char* argv[MAX_ARGC];
char pwd[SIZE];
char env[SIZE];

int lastcode = 0;

char* Home()
{
    return getenv("HOME");
}

char* Environment(int a)
{
    if(a==0)
    {
        char* username=getenv("USER");
        return username;
    }
    else if(a==1)
    {
        char* hostname=getenv("HOSTNAME");
        return hostname;
    }
    else if(a==2)
    {
        char* pwdname=getenv("PWD");
        return pwdname;
    }
}

int Interactive(char* str)
{
    printf("[%s@%s %s]$ ",Environment(0),Environment(1),Environment(2));
    fgets(str,SIZE,stdin);
    str[strlen(str)-1]=0;
    return strlen(str);
}

void Split(char* str)
{
    int i=0;
    argv[i++]=strtok(str,SEP);
    while(argv[i++]=strtok(NULL,SEP));
    if(strcmp("ls",argv[0])==0)
    {
        argv[i-1]=(char*)"--color";
        argv[i]=NULL;
    }
}

void Execute()
{
    pid_t id=fork();
    if(id==0)
    {
        execvp(argv[0],argv);
        exit(1);
    }
    int status=0;
    pid_t rid = waitpid(id,&status,0);
    if(rid==id) lastcode = WEXITSTATUS(status);
}

int BuildinCmd()
{
    int ret = 0;
    if(strcmp("cd",argv[0])==0)
    {
        ret = 1;
        char* target=argv[1];
        if(!target) target=Home();
        chdir(target);
        char temp[SIZE];
        getcwd(temp,SIZE);
        snprintf(pwd,SIZE,"PWD=%s",temp);
        putenv(pwd);
    }
    else if(strcmp("export",argv[0])==0)
    {
        ret=1;
        if(argv[1])
        {
            strcpy(env,argv[1]);
            putenv(env);
        }
    }
    else if(strcmp("echo", argv[0]) == 0)
    {
        ret = 1;
        if(argv[1] == NULL) {
            printf("\n");
        }
        else{
            if(argv[1][0] == '$')
            {
                if(argv[1][1] == '?')
                {
                    printf("%d\n", lastcode);
                    lastcode = 0;
                }
                else{
                    char *e = getenv(argv[1]+1);
                    if(e) printf("%s\n", e);
                }
            }
            else{
                printf("%s\n", argv[1]);
            }
        }
    }
    return ret;
}

int main()
{
    char commandline[SIZE];
    while(1)
    {
        int n = Interactive(commandline);
        if(n==0) continue;
        Split(commandline);
        n = BuildinCmd();
        if(n) continue;
        Execute();
    }
    return 0;
}

